﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace API.Models.Repository
{
    public class SEC_COMPANIES_ACCESS_REQUESTS_Repository : GenericRepository<PartnerDbContext, SEC_COMPANIES_ACCESS_REQUESTS>
    {
        public override IQueryable<SEC_COMPANIES_ACCESS_REQUESTS> Find(System.Linq.Expressions.Expression<Func<SEC_COMPANIES_ACCESS_REQUESTS, bool>> predicate)
        {
            IQueryable<SEC_COMPANIES_ACCESS_REQUESTS> query = _entities.SEC_COMPANIES_ACCESS_REQUESTS
                .Include("COMPANY");

            /// Фильтрация по заданному условию
            if (predicate != null)
                query = query.Where(predicate);

            return query;

            //if (session != null)
            //{
            //    query = query
            //        .Where(r => r.COMPANY_GUID == this.session.COMPANY_GUID)
            //        .AsQueryable();
            //}
        }

        public void ProvideAccess(string code)
        {
            if (this.session == null)
                throw new UnauthorizedAccessException("Сессия не указана");

            var record = new SEC_COMPANIES_ACCESS_REQUESTS
            {
                GUID_RECORD = Guid.NewGuid(),
                COMPANY_GUID = this.session.COMPANY_GUID,
                CREATE_DATE = DateTime.Now,
                EXPIRATION_DATE = DateTime.Now.AddMonths(1),
                IS_ALLOWED = false,
                SECURITY_CODE_HASH = API.Core.Util.GetMD5(code),
                USER_GUID = this.session.USER_GUID
            };

            this.Add(record);
            this.Save();
        }

        public void UseAccess(string code)
        {
            if (this.session == null)
                throw new UnauthorizedAccessException("Сессия не указана");

            var code_hash = API.Core.Util.GetMD5(code);
            var record = this
                .Find(r => 
                    !r.ACTIVATION_DATE.HasValue && 
                    r.SECURITY_CODE_HASH.Equals(code_hash))
                .SingleOrDefault();

            if (record == null)
                throw new Exception("Запись с заданным кодом не найдена");

            var access_guid = Guid.NewGuid();

            record.ALLOW_TO_GUID = this.session.COMPANY_GUID;
            record.ACTIVATION_DATE = DateTime.Now;
            record.ACTIVATION_USER_GUID = this.session.USER_GUID;
            record.ACCESS_GUID = access_guid;

            this.Edit(record);
            this.Save();

            var repository = new SEC_COMPANIES_ACCESS_Repository();
            repository.SetSession(this.session);

            repository.Add(new SEC_COMPANIES_ACCESS
            {
                GUID_RECORD = access_guid,
                COMPANY_GUID = record.COMPANY_GUID,
                ALLOW_TO_GUID = record.ALLOW_TO_GUID.Value,
                SECURITY_CODE = "9999",
                IS_ALLOWED = false
            });

            repository.Save();
        }

        public void ConfirmAccess(Guid id)
        {
            if (this.session == null)
                throw new UnauthorizedAccessException("Сессия не указана");

            var repository = new SEC_COMPANIES_ACCESS_Repository();
            repository.SetSession(this.session);

            var access = repository
                .Find(r => r.GUID_RECORD.Equals(id))
                .SingleOrDefault();

            if (access == null)
                throw new Exception("Запись не найдена");

            var record = this
                .Find(r => r.ACCESS_GUID.Value.Equals(id))
                .SingleOrDefault();

            if (record == null)
                throw new Exception("Запись не найдена");

            record.CONFIRMED_DATE = DateTime.Now;
            record.CONFIRMED_USER_GUID = this.session.USER_GUID;
            record.IS_ALLOWED = true;

            this.Edit(record);
            this.Save();

            access.IS_ALLOWED = true;
            repository.Edit(access);
            repository.Save();
        }

        /*
        public override void Add(SEC_COMPANIES_ACCESS_REQUESTS entity)
        {
            throw new NotImplementedException();
        }

        public override void Edit(SEC_COMPANIES_ACCESS_REQUESTS entity)
        {
            throw new NotImplementedException();
        }

        public override void Delete(SEC_COMPANIES_ACCESS_REQUESTS entity)
        {
            throw new NotImplementedException();
        }
        */
    }
}